<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- 
      Provide 与 Inject:
        作用：主要解决组件层级嵌套过深时，props逐级透传的问题

        provide 基本使用：
          1. provide 对象写法
            provide: {

            }
          2. provide 函数写法
            provide() {
              return {

              }
            }
          PS: 如果需要获取到当前的this，则需要写成函数返回对象的写法

        inject 基本使用：
          1. inject 数组写法
            inject: []
          2. inject 对象写法
            inject: {}

      

      Inject 注入的查找方式：
            1. 类似变量作用域一样，一层一层组件往上查找，最终找到 Root

      
     -->
    <div id="app"></div>

    <script src="../lib/vue-3.js"></script>

    <script>
      const HelloWorld = {
        template: `
          <button>HelloWorld - {{ firstName }} - {{ address }}</button>
        `,
        inject: ["firstName", "address"],
      };

      const Hello = {
        data() {
          return {};
        },
        template: `
          <div>
            <p>Hello</p>
            <p>FirstName: {{ firstName }}</p>
            <p>Address: {{ address }}</p>
          </div>
        `,
        inject: ["firstName", "address"],
      };

      const World = {
        components: {
          HelloWorld,
        },
        template: `
          <div>
            <p>{{ msg }} - World - {{ localMessage }} - {{ abc }}</p>
            <p>{{ fn1 }}</p>

            <HelloWorld />
          </div>
        `,
        inject: {
          /* 本地属性名 */ localMessage: {
            from: /* 注入来源名 */ "firstName",
          },
          // 来源简写
          abc: "address",
          msg: "firstName",
          fn1: {
            // 来源
            from: "year",
            // 默认值
            default: "2018",
          },
        },
        provide: {
          firstName: "张",
          address: "深圳",
        },
      };

      const App = {
        data() {
          return {
            firstName: "李",
          };
        },
        template: `
          <div>
            <Hello />

            <World />
          </div>
        `,
        components: {
          Hello,
          World,
        },
        // provide 对象写法
        // provide: {
        //   firstName: "李",
        //   address: "湖南",
        // },

        // provide 函数写法，优点是，可以获取到 this
        provide() {
          return {
            firstName: this.firstName,
            address: "湖南",
            year: "1998",
          };
        },
      };

      const app = Vue.createApp(App);
      app.mount("#app");
    </script>
  </body>
</html>
